<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>
        // 原型式继承
        // function Person(name) {
        //     this.name = name;
        // }
        // // 给Person对象添加一个方法
        // Person.prototype.getName = function () {
        //     return this.name;
        // }

        // // 创建一个新的User对象的构造函数
        // function User(name, password) {
        //     // 注意，这里并没有支持方便的重载/继承，也就是说，不能调用父类的构造函数
        //     this.name = name;
        //     this.password = password;
        // }
        // // User对象继承所有Person对象的方法
        // User.prototype = new Person();
        // // 添加一个新方法到User对象中
        // User.prototype.getPassword = function () {
        //     return this.password;
        // }



        // 类式继承
        // 简单的辅助函数，让你可以将新函数绑定到对象的prototype上
        // Function.prototype.method = function (name, func) {
        //     this.prototype[name] = func;
        //     return this;
        // }
        // // 一个（相当复杂的）函数，允许你方法的从其它对象继承函数
        // // 同时仍然可以调用属于父对象的那些函数
        // Function.method('inherits', function (parent) {
        //     // 记录我们目前所在父层次的级数
        //     var depth = 0;
        //     // 继承父对象的方法
        //     var proto = this.prototype = new parent();
        //     // 创建一个新的名为‘uber’的特权函数
        //     // 调用它时会执行所有在继承时被重写的函数
        //     this.method('uber', function uber(name) {
        //         var func; //要执行的函数
        //         var ret; //函数的返回值
        //         var v = parent.prototype;// 父对象的prototype
        //         // 如果我们已经在某个‘uber’函数之内
        //         if (depth) {
        //             // 上溯必要的depth，以找到原始的prototype
        //             for (var i = d; i > 0; i += 1) {
        //                 v = v.constructor.prototype;
        //             }
        //             // 从该prototype中获得函数
        //             func = v[name];
        //         }
        //         // 否则这就是‘uber’的第一次调用
        //         else {
        //             // 从prototype获得要执行的函数
        //             func = proto[name];
        //             // 如果此函数属于当前的prototype
        //             if (func == this[name]) {
        //                 // 则改为调用父对象的prototype
        //                 func = v[name];
        //             }
        //         }
        //         // 记录我们所在继承栈堆中所在位置的级数
        //         depth += 1;
        //         // 使用第一个以外所有的arguments调用此函数
        //         // 因为第一个参数是执行的函数名
        //         ret = func.apply(this, Array.prototype.slice.apply(arguments, [1]));
        //         // 恢复继承堆栈
        //         depth -= 1;
        //         // 返回执行过的函数的返回值
        //         return ret;
        //     });
        //     return this;
        // });

        // // 只继承父对象特定函数的函数，而非使用new parent()继承所有的函数
        // Function.method('swiss', function (parent) {
        //     // 遍历所有要继承的方法
        //     for (var i = 1; i < arguments.length; i++) {
        //         // 需要导入的方法名
        //         var name = arguments[i];
        //         // 将此方法导入this对象的prototype中
        //         this.prototype[name] = parent.prototype(name);
        //     }
        //     return this;
        // });


        // 类式继承
        function Father(name) {
            this.name = name;
            this.books = ['html', 'css'];
        }
        Father.prototype.sayName = function () {
            console.log('名字是', this.name);//名字是ls
        }
        function Child() { }
        // 子类的原型
        Child.prototype = new Father('ls');
        var c = new Child();
        console.log(c.name); //ls
        var c2 = new Child();
        // c.sayName();
        c.books.push('js');
        // 存在对象属性污染
        console.log(c2.books);
    </script>
</body>

</html>